/*
* Copyright (C) 2015 たんらる
*/
package fourthline.mabiicco.ui;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.InvalidDnDOperationException;
import java.util.OptionalInt;
import javax.activation.ActivationDataFlavor;
import javax.activation.DataHandler;
import javax.swing.JTabbedPane;
import javax.swing.TransferHandler;
public final class TrackTabbedPane extends JTabbedPane implements DragGestureListener {
private static final long serialVersionUID = -5972755124410009800L;
private OptionalInt targetIndex = OptionalInt.empty();
public TrackTabbedPane(IMMLManager mmlManager) {
super(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
new DragSource().createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_MOVE, this);
setTransferHandler(new TrackTabTransferHandler(this, mmlManager));
}
public boolean updateTargetIndex(OptionalInt index) {
targetIndex = index;
repaint();
return index.isPresent();
}
@Override
public void paint(Graphics g) {
super.paint(g);
if (targetIndex.isPresent()) {
Rectangle rect = getBoundsAt(targetIndex.getAsInt());
int x = rect.x;
int y = rect.height;
int xPoints[] = { x-4, x+4, x, x, x };
int yPoints[] = { 0, 0, 4, y, 4 };
g.setColor(Color.CYAN);
g.fillPolygon(xPoints, yPoints, xPoints.length);
g.setColor(Color.BLUE);
g.drawPolygon(xPoints, yPoints, xPoints.length);
}
}
@Override
public void dragGestureRecognized(DragGestureEvent event) {
Component c = event.getComponent();
if (!(c instanceof TrackTabbedPane)) {
return;
}
TrackTabbedPane tabbedPane = (TrackTabbedPane) c;
if (tabbedPane.getTabCount() > 1) {
try {
event.startDrag(DragSource.DefaultMoveDrop, new DataHandler(tabbedPane, DataFlavor.javaJVMLocalObjectMimeType));
} catch (InvalidDnDOperationException e) {
e.printStackTrace();
}
}
}
private final class TrackTabTransferHandler extends TransferHandler {
private static final long serialVersionUID = -145263268894584091L;
private final DataFlavor dataFlavor;
private final TrackTabbedPane pane;
private final IMMLManager mmlManager;
public TrackTabTransferHandler(TrackTabbedPane pane, IMMLManager mmlManager) {
super();
this.pane = pane;
this.mmlManager = mmlManager;
dataFlavor = new ActivationDataFlavor(TrackTabbedPane.class, DataFlavor.javaJVMLocalObjectMimeType, "obj/TabbedPane");
}
private OptionalInt getTargetIndex(Point p) {
for (int i = 0; i < pane.getTabCount(); i++) {
if (pane.getBoundsAt(i).contains(p)) {
if (pane.getSelectedIndex() != i) {
return OptionalInt.of(i);
} else {
break;
}
}
}
return OptionalInt.empty();
}
@Override
public boolean canImport(TransferSupport support) {
int action = support.getDropAction();
if (action == MOVE) {
if (support.isDataFlavorSupported(dataFlavor)) {
Point dropPoint = support.getDropLocation().getDropPoint();
if (pane.updateTargetIndex(getTargetIndex(dropPoint))) {
return true;
}
}
}
return false;
}
@Override
public boolean importData(TransferSupport support) {
Point dropPoint = support.getDropLocation().getDropPoint();
int toIndex = getTargetIndex(dropPoint).getAsInt();
mmlManager.moveTrack(toIndex);
pane.updateTargetIndex(OptionalInt.empty());
return true;
}
}
}